﻿using System.Collections.Generic;
using System.Linq;

namespace WCFPeerResolver
{
    /// <summary>
    /// Manages the meshes available.
    /// </summary>
    public class MeshManager : IEnumerable<Mesh>
    {
        private readonly Dictionary<string, Mesh> m_Meshes = new Dictionary<string, Mesh>();

        /// <summary>
        /// Get mesh by specified ID.
        /// </summary>
        /// <param name="meshID">ID of mesh to receive.</param>
        /// <returns>The mesh or null if no mesh exists.</returns>
        public Mesh Get(string meshID)
        {
            Mesh mesh;

            m_Meshes.TryGetValue(meshID, out mesh);

            return mesh;
        }

        /// <summary>
        /// Get or create a mesh by specified ID
        /// </summary>
        /// <param name="meshID">The id of the mesh to get or create if it does not exist.</param>
        /// <returns>Allways returns a mesh.</returns>
        public Mesh GetOrCreate(string meshID)
        {
            Mesh mesh;

            if (!m_Meshes.TryGetValue(meshID, out mesh))
            {
                mesh = new Mesh(meshID);
                m_Meshes.Add(meshID, mesh);
            }

            return mesh;
        }

        /// <summary>
        /// Clean up dead meshes and mesh entries.
        /// </summary>
        /// <remarks>This method is for internal use only.</remarks>
        /// <param name="time"></param>
        /// <param name="cleanupInterval"></param>
        internal void Cleanup(System.DateTime time, System.TimeSpan cleanupInterval)
        {
            string[] meshes = m_Meshes.Values.Where(p => time - p.Updated > cleanupInterval).Select(p => p.MeshID).ToArray();

            foreach (string mesh in meshes)
            {
                m_Meshes.Remove(mesh);
            }

            foreach (Mesh mesh in m_Meshes.Values)
            {
                mesh.Cleanup(time, cleanupInterval);
            }
        }

        #region IEnumerable<Mesh> Members

        public IEnumerator<Mesh> GetEnumerator()
        {
            return m_Meshes.Values.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            throw new System.NotImplementedException();
        }

        #endregion
    }
}